package com.lyncc.netty.codec.lengthFieldBasedFrame;

 
import java.nio.charset.Charset;

import io.netty.buffer.ByteBuf;

import io.netty.channel.ChannelHandlerContext;

import io.netty.handler.codec.LengthFieldBasedFrameDecoder;

 
public class CustomDecoder extends LengthFieldBasedFrameDecoder {

 
//判断传送客户端传送过来的数据是否按照协议传输，头部信息的大小应该是 byte+byte+int = 1+1+4 = 6

private static final int HEADER_SIZE = 6;

 
private byte type;

 
private byte flag;

 
private int length;

 
private String body;

 
/**

*

* @param maxFrameLength 解码时，处理每个帧数据的最大长度

* @param lengthFieldOffset 该帧数据中，存放该帧数据的长度的数据的起始位置

* @param lengthFieldLength 记录该帧数据长度的字段本身的长度

* @param lengthAdjustment 修改帧数据长度字段中定义的值，可以为负数

* @param initialBytesToStrip 解析的时候需要跳过的字节数

* @param failFast 为true，当frame长度超过maxFrameLength时立即报TooLongFrameException异常，为false，读取完整个帧再报异常

*/

public CustomDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength,

int lengthAdjustment, int initialBytesToStrip, boolean failFast) {

super(maxFrameLength, lengthFieldOffset, lengthFieldLength,

lengthAdjustment, initialBytesToStrip, failFast);

}

 
@Override

protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {

if (in == null) {

return null;

}

if (in.readableBytes() < HEADER_SIZE) {

throw new Exception("可读信息段比头部信息都小，你在逗我？");

}

 
//注意在读的过程中，readIndex的指针也在移动

type = in.readByte();

 
flag = in.readByte();

 
length = in.readInt();
String data = in.toString(Charset.forName("UTF8"));
System.out.println(data);

 System.out.println(in.readableBytes());
if (in.readableBytes() < length) {

throw new Exception("body字段你告诉我长度是"+length+",但是真实情况是没有这么多，你又逗我？");

}

ByteBuf buf = in.readBytes(length);

byte[] req = new byte[buf.readableBytes()];

buf.readBytes(req);

body = new String(req, "UTF-8");

 
CustomMsg customMsg = new CustomMsg(type,flag,length,body);

return customMsg;

}

 
}
